package org.fastsyncer.rest.interceptor;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.constant.CommonConstant;
import org.fastsyncer.common.constant.ThirdpartyConstant;
import org.fastsyncer.common.util.ApplicationUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 登录拦截器
 * 
 * @ClassName: AostarOAuthInterceptor
 * @Description: 登录拦截器：验证用户操作访问权限
 * @author AE86
 * @date: 2017年7月6日 下午10:42:18
 */
public class AostarOAuthInterceptor implements HandlerInterceptor {
    // 认证服务地址
    private static String ssoUrl = ApplicationUtil.getKey(ThirdpartyConstant.THIRDPARTY_APP_OATUTH_SSOURL);
    // 颁发的OAUTH客户端ID
    private static String clientId = ApplicationUtil.getKey(ThirdpartyConstant.THIRDPARTY_APP_OATUTH_CLIENTID);
    // 颁发的OAUTH客户端秘钥
    private static String clientSecret = ApplicationUtil.getKey(ThirdpartyConstant.THIRDPARTY_APP_OATUTH_CLIENTSECRET);
    // 回调地址
    private static String redirectUrl = ApplicationUtil.getKey(CommonConstant.SERVER_SERVICE_ADDRESS);
    
    /**
     * 首页地址
     */
    private static final String MAIN_URL = ApplicationUtil.getKey(CommonConstant.SERVER_SERVICE_ADDRESS);
    /**
     * 本机认证地址
     */
    private static final String LOGIN_URL = ApplicationUtil.getKey(CommonConstant.SERVER_SERVICE_ADDRESS_AUTHENTICATE);
    /**
     * OAuth认证地址
     */
    private static final String OAUTH_URL = ssoUrl + "/oauth2.0/authorize?client_id=" + clientId + "&redirect_uri=" + redirectUrl;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            // 验证session会话
            HttpSession session = request.getSession();
            if(Ticket.validateTicket(session)){
                return true;
            }

            // 如果有应用ID属性说明是通过集成业务系统登录
            String appKey = ApplicationUtil.getKey(ThirdpartyConstant.THIRDPARTY_APP_APPID);
            String appVal = (String) session.getAttribute(appKey);
            if (StringUtils.isBlank(appVal)) {
                // 获取系统项目路径
                response.sendRedirect(LOGIN_URL);
                return false;
            }

            // 如果票据不为空,进行下一步逻辑校验
            String code = request.getParameter("code");
            if (StringUtils.isEmpty(code)) {
                // 如果票据为空重定向到sso，进行逻辑校验，如果无法获取st则跳转到sso登录页面，如果获取到st，将st做为code参数跳转到该servlet，该servlet拿到code以后进行下一步逻辑校验
                response.sendRedirect(OAUTH_URL);
                return false;
            }
            // 发送accessToken请求，根据sso分配的clientId、clientSecret以及获取到的ST票据获取TGT票据
            String url = ssoUrl + "/oauth2.0/accessToken";
            String param = "client_id=" + clientId + "&redirect_uri=" + redirectUrl + "&client_secret=" + clientSecret + "&code=" + code;
            // 发送profile请求，根据上一步返回的TGT票据获取登录用户属性
            String url2 = ssoUrl + "/oauth2.0/profile";
            // 返回值为TGT票据
            String tgt = sendGet(url, param);
            // 认证成功，返回登录用户属性
            // 此实例将用户信息response出去，应用系统可根本自身场景处理
            String userinfoJson = sendGet(url2, tgt);
            
            // 将票据写入浏览器
            Ticket.createTicket(request, userinfoJson);
            response.sendRedirect(MAIN_URL);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = new StringBuilder().append(url).append("?").append(param).append("&isAssembly=true").toString();
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
            }
        }
        return result;
    }

}
